package com.gsma.calendar.android.db;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;

import com.gsma.calendar.android.db.CalendarGsmaDBSchema.Tables;
import com.gsma.calendar.android.model.CalendarObject;
import com.gsma.calendar.android.model.GlobalEvent;
import com.gsma.calendar.android.util.Config;

public class CalendarGSMAProvider extends ContentProvider {

	private DatabaseController mDatabase;
	private Context context;

	private static final UriMatcher sUriMatcher = buildUriMatcher();
	private static final int CALENDAR_GSMA = 100;
	private static final int GLOBAL_EVENT = 101;

	private static UriMatcher buildUriMatcher() {
		final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
		final String authority = CalendarGsmaDBSchema.CONTENT_AUTHORITY;

		matcher.addURI(authority, Tables.CALENDAR_GSMA, CALENDAR_GSMA);
		matcher.addURI(authority, Tables.GLOBAL_EVENT , GLOBAL_EVENT);
		return matcher;
	}

	private String getTable(final Uri uri) {
		switch (sUriMatcher.match(uri)) {
		case CALENDAR_GSMA:
			return Tables.CALENDAR_GSMA;
		case GLOBAL_EVENT:
			return Tables.GLOBAL_EVENT;
		default:
			throw new UnsupportedOperationException("Unknown query uri: " + uri);
		}

	}

	@Override
	public boolean onCreate() {
		context = getContext();
		mDatabase = new DatabaseController(context);
		return true;
	}

	@Override
	public String getType(Uri uri) {
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case CALENDAR_GSMA:
			return CalendarObject.CONTENT_TYPE;
		case GLOBAL_EVENT:
			return GlobalEvent.CONTENT_TYPE;
		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		final SQLiteDatabase db = mDatabase.getWritableDatabase();
		final SelectionBuilder builder = buildSimpleSelection(uri);
		return builder.where(selection, selectionArgs).delete(db);
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		final SQLiteDatabase db = mDatabase.getWritableDatabase();
		db.insertOrThrow(getTable(uri), null, values);
		return uri;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		final SQLiteDatabase db = mDatabase.getReadableDatabase();

		final int match = sUriMatcher.match(uri);
		final SQLiteQueryBuilder builder = buildExpandedSelection(uri, match);

		switch (match) {
		case CALENDAR_GSMA:
			break;
		case GLOBAL_EVENT:
			break;
		default:
			break;
		}

		return builder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
	}

	private SQLiteQueryBuilder buildExpandedSelection(Uri uri, int match) {
		final SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
		switch (match) {
		case CALENDAR_GSMA: {
			builder.setTables(Tables.CALENDAR_GSMA);
			break;
		}
		case GLOBAL_EVENT: {
			builder.setTables(Tables.GLOBAL_EVENT);
			break;
		}

		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);

		}
		return builder;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

		Log.d(Config.LOG_TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
		final SQLiteDatabase db = mDatabase.getWritableDatabase();
		final SelectionBuilder builder = buildSimpleSelection(uri);
		return builder.where(selection, selectionArgs).update(db, values);

	}

	private SelectionBuilder buildSimpleSelection(Uri uri) {
		final SelectionBuilder builder = new SelectionBuilder();
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case CALENDAR_GSMA: {
			return builder.table(Tables.CALENDAR_GSMA);
		}

		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);

		}
	}

}
